最近需要分析一些数据,发现Hadoop正适合对大量监视数据进行提取和分析,遂搭建一个可开发和运行的Hadoop单机模式平台。
在搭建过程中,会遇到一些大大小小的坑坑洞洞,如果有发现新的问题,请作出合理的判断来解决遇到的问题,本文给出的过程乃综合网络上的一些官方教程与前辈们的总结教程,亲手搭建测试记录而来。
##初步设置系统环境
###所需要的系统安装环境
系统环境安装于VMWare虚拟机当中
- 60G 虚拟硬盘空间
- Ubuntu Gnome 16.04 (建议14.04,可以使用Xorg视频驱动提高性能)
- JDK 7+
- IntelliJ IDEA 2016.1 或 Spring Tools Suits
- Hadoop-2.6.4.tar.gz 包下载好
因为我们希望在Ubuntu中使用IDEA对项目的代码进行编辑,因此使用Gnome版。 我们当下使用的用户是hadoop用户,让我们的开发环境和Hadoop进程都在这个用户下运行,因此我们要让hadoop用户成为系统管理员(这一过程在安装系统时可以直接设置,无需命令,如果使用现有虚拟机,请使用adduser命令和usermod命令来修改)。
###必要的预备措施 Hadoop在使用过程中,需要无密码直接登录的ssh服务,因此我们需要提前安装ssh服务(不是客户端命令,ssh客户端已经预装)。
$ sudo apt-get install openssh-server
重启系统或者启动服务:
$ sudo /etc/init.d/ssh start
我们查看ssh代理进程是否存在
$ ps -e |grep ssh
如果终端上返回了:
1190 ? 00:00:00 sshd
1720 ? 00:00:00 ssh-agent
那表明ssh代理进程和服务都已经正常启动。
接下来要配置本机的ssh免密登录,执行ssh-keygen生成密钥对
$ ssh-keygen -t rsa -P ""
屏幕提示可以按Enter继续,可能会多按几次Enter。最后会在用户的家目录~/下放置一个.ssh目录,并且存入id_rsa和id_rsa.pub,前面是私钥,后面是公钥,私钥一定要好好保管。
生成密钥对以后,要将公钥放到认证文件里,这个文件是~/.ssh/authorized_keys
,如果不存在的话可以用touch
命令来生成空文件。然后使用下面的命令来追加公钥,
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
最后,我们可以测试一下ssh登入本机是否无需输入密码:
$ ssh localhost
如果仍然提示输入密码,修改权限为
/home
| hadoop(用户名家目录) 700
|- | .ssh 700
|- | authorized_keys 600
###安装JDK和Hadoop 执行命令
$ sudo apt-get install -y openjdk-8-jdk
建议将/usr/lib/jvm/
下的jdk目录作为JAVA_HOME记录到环境变量中。
我们解压缩hadoop-2.6.4.tar.gz,版本可以是2.x.x,但是大版本号最好与本文的版本相同。
$ tar -xzf hadoop-2.6.4.tar.gz
请记住你所解压的hadoop目录的位置,或者将hadoop目录的位置写到环境变量HADOOP_HOME
中。另外也要将\$HADOOP_HOME/bin
和\$HADOOP_HOME/sbin
目录增加到PATH环境变量中。
常见的一种记录环境变量方式是在/etc/profile使用export命令导出环境变量。我们可以通过
$ sudo gedit /etc/profile
编辑这个文件,然后再文件头加入
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export HADOOP_HOME=/home/hadoop/hadoop-2.6.4/
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
#其他需要的环境变量可以继续追加
退出后,可以使用
$ source /etc/profile
让环境变量设置生效
如果不放心,可以用env命令看一下所有的环境变量是否成功应用到系统中,也可以通过env |grep '特定变量名'
来查看特定的变量是否存在。
###对Hadoop进行配置
我们需要对一个单机模式的hadoop进行开发,但是还需要一点配置。
首先我们需要对$HADOOP_HOME/etc/hadoop/core-site.xml
文件机型修改,请记住hdfs配置的端口号,本例端口号为9000
:
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
</configuration>
并且修改etc/hadoop/hdfs-site.xml
:
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>
另外,我们还需要对$HADOOP_HOME/etc/hadoop/hadoop-env.sh
文件进行一定的修改,这一步不能省略:
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
接下来我们开始准备格式化hdfs(hdfs执行文件存于$HADOOP_HOME/bin中):
$ hdfs namenode -format
现在我们可以启动名称节点和数据节点守护进程(该脚本(hdfs执行文件存于$HADOOP_HOME/sbin中)):
$ start-dfs.sh
停止时使用
$ stop-dfs.sh
#2.配置单机模式的YARN
开发期间我们也使用单机模式的MapReduce框架YARN,因此也需要一些简单配置。
$HADOOP_HOME
目录中etc/hadoop/mapred-site.xml
:
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
修改$HADOOP_HOME
目录中etc/hadoop/yarn-site.xml
:
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
保存后退出gedit。 最后我们可以启动我们的yarn了。
$ start-yarn.sh
现在我们需要查验一下,DFS和YARN启动以后服务是否都正常启动:
$ jps
Java虚拟机进程当中如果如下所示:
6112 NameNode
7027 Jps
6229 DataNode
6582 ResourceManager
6701 NodeManager
6429 SecondaryNameNode
那么hadoop的分布式存储和MapReduce框架这就搭建完成了。
如果jps的进程当中带有jar的进程,那说明你已经提交了的jar包到hdfs并开始执行jar中的任务了。
如此一来可以打开浏览器进入Hadoop集群页面,查看集群当中运行的节点、应用任务和调度任务。 如下图所示:
另外,运行的任务因为会打包为jar文件上传到hdfs中,我们可以从浏览器进入HDFS概览页面查看HDFS集群仪表盘,数据节点状态以及已存的任务文件。
如下图所示:
###开发环境搭建过程的坑和一些问题:
####1、纯Linux的问题
如果.ssh
目录和authorized_keys
的文件权限配置不正确,ssh免密登录是不能用的,.ssh
目录树的权限配置在文中已有说明。
用户家目录和.ssh权限为700,authorized_keys
文件权限为600。
####2、未指定hadoop的临时目录使用默认目录,默认临时目录因为不存在,无法启动NameNode的问题 启动Hadoop本地失败时,一般伴随的是NameNode启动的失败,NameNode是用于保存DataNode上文件分块的元数据的主要节点,它启动的失败无非是因为hdfs启动过程有问题。其中一个常见问题就是临时目录因不存在无法启动的问题,我们在配置hadoop配置文件的时候并没有指定临时目录,因此使用默认目录,而默认目录是不存在的,因此会报如下异常:
org.apache.hadoop.hdfs.server.common.InconsistentFSStateException: Directory /tmp/hadoop-gin/dfs/name is in an inconsistent state: storage directory does not exist or is not accessible.
at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverStorageDirs(FSImage.java:314)
at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverTransitionRead(FSImage.java:202)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFSImage(FSNamesystem.java:1022)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFromDisk(FSNamesystem.java:741)
at org.apache.hadoop.hdfs.server.namenode.NameNode.loadNamesystem(NameNode.java:538)
at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:597)
at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:764)
at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:748)
at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1441)
at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1507)
这段异常代码是从hadoop记录的文件日志中得到的,日志文件的路径一般为$HADOOP_HOME/logs/
目录中,而我们在启动过程中是NameNode启动失败了,那么我们就要找hadoop-当前运行的用户名-namenode-gin-virtual-machine.log
文件。
解决上面异常发生的问题,其实也简单,只要执行命令
$ mkdir /tmp/hadoop-gin/dfs/name
让这个目录存在就可以了。
####3、未格式化NameNode导致启动失败 一般问题2发生后解决了该问题会随之发生本问题,异常会在日志文件中如下打印:
org.apache.hadoop.hdfs.server.namenode.NameNode: Failed to start namenode.
java.io.IOException: NameNode is not formatted.
at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverTransitionRead(FSImage.java:212)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFSImage(FSNamesystem.java:1022)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFromDisk(FSNamesystem.java:741)
at org.apache.hadoop.hdfs.server.namenode.NameNode.loadNamesystem(NameNode.java:538)
at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:597)
at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:764)
at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:748)
at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1441)
at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1507)
解决问题的方法也好办,执行
$ hdfs namenode -format
可解决。
- 注意:以上命令都是以关键路径存在于环境变量PATH下才可以正常执行。否则请使用绝对路径执行。
下一部分我将会介绍Spring.io官网上YARN操作范例在Hadoop中的运行。这一部分需要STS编辑器或者IntelliJ IDEA编辑器的支持,并且对gradle构建工具有一点了解。